﻿//==================================BoxBlurAlgorithm.cs=================================\\
//===Michiel van der Winden======\\

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Collections;

namespace Team2_Vision
{
    class BoxBlur : VisionAlgorithm
    {
        public BoxBlur(String name) : base(name) { }
        public override System.Drawing.Bitmap DoAlgorithm(System.Drawing.Bitmap sourceImage, int matrix)
        {
            Bitmap returnImage = new Bitmap(sourceImage);
            BitmapData sourceImageData = sourceImage.LockBits(new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            BitmapData returnImageData = returnImage.LockBits(new Rectangle(0, 0, returnImage.Width, returnImage.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            IntPtr adressreturn = returnImageData.Scan0;
            IntPtr adresssource = sourceImageData.Scan0;

            int arraygrootte = sourceImage.Width * sourceImage.Height * 3;
            //int matrix = 11;
            int midden = (matrix / 2);
            int teller = 0;
            int value = 0;

            byte[] array_from_source = new byte[arraygrootte];
            byte[] array_red = new byte[arraygrootte / 3];
            byte[] array_back = new byte[arraygrootte];

            Marshal.Copy(adresssource, array_from_source, 0, arraygrootte);

            //maak een array met alle rode waardes;

            for (int i = 0; i < arraygrootte / 3; i++)
            {
                array_red[i] = (byte)((array_from_source[i * 3] + array_from_source[(i * 3) + 1] + array_from_source[(i * 3) + 2]) / 3);
            }
           

            for (int y = midden; y < sourceImage.Height - midden; y++)
            {
                
                teller = 0;
                //maak nieuwe matrix
                for (int my = -midden; my <= midden; my++)
                {
                    for (int mx = 0; mx < matrix; mx++)
                    {
                        teller += array_red[(((y + my) * sourceImage.Width) + mx)];
                    }
                }
                for (int x = midden + 1; x < sourceImage.Width - midden; x++)
                {
                    //matrix selecteren
                    for (int my = -midden; my <= midden; my++)
                    {
                        teller -= array_red[(((y + my) * sourceImage.Width) + x - midden - 1)];
                        teller += array_red[(((y + my) * sourceImage.Width) + x + midden)];
                    }
                    value = teller / (matrix * matrix);

                    //median terug zetten
                    array_back[((y * sourceImage.Width * 3) + x * 3)] = (byte)value;
                    array_back[((y * sourceImage.Width * 3) + x * 3) + 1] = (byte)value;
                    array_back[((y * sourceImage.Width * 3) + x * 3) + 2] = (byte)value;
                }
            }

            Marshal.Copy(array_back, 0, returnImageData.Scan0, arraygrootte);
            returnImage.UnlockBits(returnImageData);
            sourceImage.UnlockBits(sourceImageData);
            return returnImage;
        }
    }
}